package sysUtil

import sysAuth.SysNoticeController

/**
 * Created by Administrator on 2019-04-17.
 */
class EchartUtil {

    /**
     *
     * @param data 数据结果集
     * @param opt_series_cfg_type 系列配置源
     * @param default_series 默认系列
     * @param diy_series 自定义系列配置
     * @return
     */
    static getEchartSeries(dataList,classFlag,opt_series_cfg_type,default_series,diy_series){
        def data
        switch (classFlag){
            case "xd-panel-echart-line"://折线
                data = getEchartLine(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-bar"://柱状图
                data = getEchartLine(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-pie"://饼图
                data = getEchartPie(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-funnel"://漏斗图
                data = getEchartPie(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-gauge"://仪表盘
                data = getEchartPie(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-scatter"://仪表盘
                data = getEchartLine(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
            case "xd-panel-echart-radar"://雷达
                data = getEchartRadar(dataList,opt_series_cfg_type,default_series,diy_series)
                break;
        }
        return  data
    }

    /**
     * 生成雷达
     * @param dataList
     * @param series_cfg_type
     * @param default_series
     * @param diy_series
     * @return
     */
    static getEchartRadar(List<Map> dataList,Map  series_cfg_type,String default_series,String diy_series){
        def opt_series_cfg_type = series_cfg_type.get("opt_series_cfg_type")
        def result = new net.sf.json.JSONArray()
        if(opt_series_cfg_type == "fieldValue"){//如果系列使用字段值
            def fixedDataMap = fixedDataRadarByFieldValue( dataList, series_cfg_type)
            def diySeriesJson = SysCommUtil.parseObj2Json(diy_series)
            result = createSeriesMAPRadar(fixedDataMap,diySeriesJson,default_series)
        }else{//如果系列使用字段名:fieldName ,目前只有雷达图不支持系统名
        }
        return   result
    }

    /**
     * 雷达图
     * @param fixedDataMap
     * @param diySeriesJson
     * @param default_series
     */
    static createSeriesMAPRadar(Map fixedDataMap,Map diySeriesJson,String default_series){
        def result = new net.sf.json.JSONArray()
        def default_series_json = SysCommUtil.parseObj2Json(default_series)
        fixedDataMap.each {seriesKey,seriesDataMap ->
            def series =  SysCommUtil.parseObj2Json(null)
            if(diySeriesJson.keySet().contains(seriesKey)){
                series = SysCommUtil.parseObj2Json(diySeriesJson.get(seriesKey))
                series.put("areaStyle",series.get("series_areaStyle"))
                series.put("itemStyle",[color:series.get("series_itemStyle_color")])
            }
            series.put("name",seriesKey)
            series.put("value",seriesDataMap)
            result.add(series)
        }
        default_series_json.put("data",result)
        return default_series_json
    }

    /**
     * 获取雷达radar配置
     */
    static getRadar(List<Map> dataList,Map  series_cfg_type,String radarStr){
        def opt_series_cfg_type = series_cfg_type.get("opt_series_cfg_type")
        def radarJson = SysCommUtil.parseObj2Json(BeetlUtil.getStrTemplateForEchart(null,radarStr))
        if(opt_series_cfg_type == "fieldValue"){//如果系列使用字段值
            def weiDu =  series_cfg_type.get("opt_series_cfg_weidu")
            //def fieldValue = series_cfg_type.get("fieldValue@valueField")
            //def scale = series_cfg_type.get("fieldValue@scale")
            def weiDuList = dataList["${weiDu}"].unique()
            def midData = dataList.groupBy{
                it[weiDu]
            }
            def indicator = []
            weiDuList.each {
                def data = midData.get(it)
                indicator.add([text:it,max: EchartUtil.getScaleRadarData(data["indicator"]?:data["INDICATOR"]) ])
            }
            radarJson.put("indicator",indicator)
        }else{//如果系列使用字段名:fieldName
            //def fixedDataMap = fixedDataRadarByFieldName( dataList, series_cfg_type)
        }
        return radarJson
    }

    /**
     * 雷达图：系列使用字段值，根据配置的系列,组织结果集
     * @param dataList
     * @param series_cfg_type
     * @return
     */
    static fixedDataRadarByFieldValue(List<Map>dataList,Map series_cfg_type){
        //根据dataList生成系列清单
        def fieldName = series_cfg_type.get("fieldValue@nameField")
        def fieldValue = series_cfg_type.get("fieldValue@valueField")
        def weiDu =  series_cfg_type.get("opt_series_cfg_weidu")
        def scale = series_cfg_type.get("fieldValue@scale")
        def weiDuList = dataList["${weiDu}"].unique()
        //根据scale重新组织数据
        def midData = dataList.groupBy{
            it[fieldName]
        }
        Map<String,Map> midDataList =  new HashMap()
        midData.each {key,valueList->
            def newValueList = valueList.groupBy{
                it[weiDu]
            }
            Map list1 = new HashMap()
            newValueList.each {weiDuKey,list->
                list1.put(weiDuKey,EchartUtil.getScaleData(list[fieldValue],scale))
            }
            midDataList.put(key,list1)
        }
        def fixedDataMap =[:]
        midDataList.each {seriesName,seriesData->
            def data = []
            for(String str:weiDuList){
                data.add(seriesData.get(str)?:0)
            }
            fixedDataMap.put(seriesName,data)
        }
        return  fixedDataMap
    }


    /**
     * 雷达图：系列使用字段名，根据配置的系列,组织结果集
     * @param dataList
     * @param series_cfg_type
     */
    static fixedDataRadarByFieldName(List<Map>dataList,Map<String,Object> series_cfg_type){
        def weiDu =  series_cfg_type.get("opt_series_cfg_weidu")
        def seriesCfg = [:]
        series_cfg_type.each {key,value ->
            if(  series_cfg_type.get("fieldName@${value}") == value  ){
                seriesCfg.put(value,series_cfg_type.get("fieldName@${value}@scale"))
            }
        }
        def midDataMap = dataList.groupBy {it[weiDu]}
        def fixedDataMap = [:]
        seriesCfg.each {seriesName,scale ->
            def data = []
            midDataMap.each {weiDuKey,midDataList ->
                def tempData = getScaleData(midDataList[seriesName],scale)
                data.add([weiDuKey,tempData])
            }
            fixedDataMap.put(seriesName,data)
        }
        return fixedDataMap
    }



    static getEchartPie(List<Map> dataList,Map  series_cfg_type,String default_series,String diy_series){
        def opt_series_cfg_type = series_cfg_type.get("opt_series_cfg_type")
        def result = new net.sf.json.JSONArray()
        if(opt_series_cfg_type == "fieldValue"){//如果系列使用字段值
            def fixedDataMap = fixedDataMapByFieldValue( dataList, series_cfg_type)
            def diySeriesJson = SysCommUtil.parseObj2Json(diy_series)
            result = createSeriesMAP(fixedDataMap,diySeriesJson,default_series)
        }else{//如果系列使用字段名:fieldName
            def fixedDataMap = fixedDataMapByFieldName( dataList, series_cfg_type)
            def diySeriesJson = SysCommUtil.parseObj2Json(diy_series)
            result = createSeriesMAP(fixedDataMap,diySeriesJson,default_series)
        }
        return   result
    }

    static getEchartLine(List<Map> dataList,Map  series_cfg_type,String default_series,String diy_series){
        def opt_series_cfg_type = series_cfg_type.get("opt_series_cfg_type")
        def result = new net.sf.json.JSONArray()
        if(opt_series_cfg_type == "fieldValue"){//如果系列使用字段值
            def fixedDataMap = fixedDataMapByFieldValue( dataList, series_cfg_type)
            def diySeriesJson = SysCommUtil.parseObj2Json(diy_series)
            result = createSeries(fixedDataMap,diySeriesJson,default_series)
        }else{//如果系列使用字段名:fieldName
            def fixedDataMap = fixedDataMapByFieldName( dataList, series_cfg_type)
            def diySeriesJson = SysCommUtil.parseObj2Json(diy_series)
            result = createSeries(fixedDataMap,diySeriesJson,default_series)
        }
        return   result
    }


    /**
     * 生成Map形式系列data:[{name:'',value}]
     * @param fixedDataMap
     * @param diySeriesJson
     * @param default_series
     * @return
     */
    static createSeriesMAP(Map<String,List<List>>fixedDataMap,diySeriesJson,default_series){
        def result = new net.sf.json.JSONArray()
        fixedDataMap.each {seriesName,seriesData ->
            def series =  SysCommUtil.parseObj2Json(null)
            if(diySeriesJson.keySet().contains(seriesName)){
                series = SysCommUtil.parseObj2Json(BeetlUtil.getStrTemplateForEchart(diySeriesJson.get(seriesName),default_series))
            }else{
                series =  SysCommUtil.parseObj2Json(BeetlUtil.getStrTemplateForEchart([series_name:seriesName],default_series))
            }
            def pieList  = new net.sf.json.JSONArray()
            seriesData.each{
                def pieData  = new net.sf.json.JSONObject()
                pieData.put("name",it.get(0))
                pieData.put("value",it.get(1))
                pieList.add(pieData)
            }
            series.put("data",pieList)
            result.add(series)
        }
        return result
    }

    /**
     * 生成List形式系列data:[key,keyDataList]
     * @param fixedDataMap
     * @param diySeriesJson
     * @param default_series
     * @return
     */
    static createSeries(fixedDataMap,diySeriesJson,default_series){
        def result = new net.sf.json.JSONArray()
        fixedDataMap.each {seriesName,seriesData ->
            def series =  SysCommUtil.parseObj2Json(null)
            if(diySeriesJson.keySet().contains(seriesName)){
                series = SysCommUtil.parseObj2Json(BeetlUtil.getStrTemplateForEchart(diySeriesJson.get(seriesName),default_series))
            }else{
                series =  SysCommUtil.parseObj2Json(BeetlUtil.getStrTemplateForEchart([series_name:seriesName],default_series))
            }
            series.put("data",seriesData)
            result.add(series)
        }
        return result
    }
    /**
     * 系列使用字段名，根据配置的系列,组织结果集
     * @param dataList
     * @param series_cfg_type
     */
    static fixedDataMapByFieldName(List<Map>dataList,Map<String,Object> series_cfg_type){
        def weiDu =  series_cfg_type.get("opt_series_cfg_weidu")
        def seriesCfg = [:]
        series_cfg_type.each {key,value ->
            if(  series_cfg_type.get("fieldName@${value}") == value  ){
                seriesCfg.put(value,series_cfg_type.get("fieldName@${value}@scale"))
            }
        }
        def midDataMap = dataList.groupBy {it[weiDu]}
        def fixedDataMap = [:]
        seriesCfg.each {seriesName,scale ->
            def data = []
            midDataMap.each {weiDuKey,midDataList ->
                def tempData = getScaleData(midDataList[seriesName],scale)
                data.add([weiDuKey,tempData])
            }
            fixedDataMap.put(seriesName,data)
        }
        return fixedDataMap
    }

    /**
     * 系列使用字段值，根据配置的系列,组织结果集
     * @param dataList
     * @param series_cfg_type
     * @return
     */
    static fixedDataMapByFieldValue(List<Map>dataList,Map series_cfg_type){
        //根据dataList生成系列清单
        def fieldName = series_cfg_type.get("fieldValue@nameField")
        def fieldValue = series_cfg_type.get("fieldValue@valueField")
        def weiDu =  series_cfg_type.get("opt_series_cfg_weidu")
        def scale = series_cfg_type.get("fieldValue@scale")

        //根据scale重新组织数据
        def midData = dataList.groupBy{
            it[fieldName]
        }
        //定义修正后的数据结构
        def fixedDataMap =[:]
        midData.each {key,valueList->
            def newValueList = valueList.groupBy{
                it[weiDu]
            }
            def tempMap = [ ]
            newValueList.each {target,targetList->
                //遍历DataList，根据汇总方式fieldName@scale，计算后，生成series
                def tempData = getScaleData(targetList[fieldValue],scale)
                tempMap.add([target,tempData])
            }
            fixedDataMap.put(key,tempMap)
        }
        return  fixedDataMap
    }

    /**
     * 根据scale计算list值
     * @param list
     * @param scale
     * @return
     */
    static getScaleData(list,scale){
        def tempData = 0
        if(list){
            switch (scale){
                case "sum":
                    tempData = list.sum()
                    break;
                case "max":
                    tempData = list.max()
                    break;
                case "min":
                    tempData = list.min()
                    break;
                case "avg":
                    if(list.size()!=0){
                        tempData =  list.sum() / list.size()
                    }
                    break;
                case "count":
                    tempData = list.size()
                    break;
                default:
                    tempData = list.get(0)
                    break;
            }
        }
        return tempData
    }
    /**
     * 根据scale计算list值
     * @param list
     * @param scale
     * @return
     */
    static getScaleRadarData(List list){
        def tempData = 0
         if(list){
             tempData = list.get(0)
         }
        return  tempData
    }
}
